/*
# File    :   fsm.h
# Author  :   toujizhe,         schips
# Git     :   https://gitee.com/schips/
# Ref     :   https://www.cnblogs.com/toujizhe/articles/5473489.html
# Date    :   2016-05-09 12:20, 2019-05-20 13:14:52  
# Describe:     
              一个可以复位到状态机，根据ref的源码进行改善
              理论上可以设置状态机为任何状态，
              但是现在只提供重置为初始化状态的接口。
*/
#ifndef __FSM_H_
#define __FSM_H_
/* ----------------------- Defines ------------------------------------------*/
// 数据类型定义区
typedef unsigned char State;
typedef State(*Procedure)(void *);
typedef struct _SM_STATE {
    State cs;       // 当前状态
    State ns;       // 下个状态
} SM_STATE;

typedef struct _SM_VALUE {
    // 自定义数据结构
    int cnt;
} SM_VALUE;

// 状态机参数
typedef struct _SM_VAR {
    // 现在的状态以及下个状态
    SM_STATE st;

    // 状态机数据区域
    SM_VALUE var;
} SM_ARG;

/* ----------------------- Static functions ---------------------------------*/


void EmyptData(void *arg);
State step_init(void * arg);
State step_count(void * arg);//计数
State step_done(void * arg);//计数完成
State step_default(void * arg);//错误过程

//状态定义(这里的顺序要求与 Steps[] 一致)
enum states{ s_init, s_count, s_done, s_default};
// 函数指针 （相当于函数入口）
static Procedure Steps[] = { step_init, step_count, step_done, step_default };


/* ----------------------- Start implementation -----------------------------*/

static inline void SetNextState(void*arg, State st)
{
    SM_ARG *p = (SM_ARG *)arg;
    p->st.ns = st;
}

static inline int BestStateMachine(void *arg)
{
    SM_ARG *p = (SM_ARG *)arg;

    // 记录当前状态
    p->st.cs = p->st.ns;

    // 根据现在情况得到下一个阶段到状态
    p->st.ns = Steps[p->st.cs](arg);
    
    // 返回当前状态（可根据需要修改）
    return p->st.cs;
}


// 复位到初始情况
static inline void ResetStateMachine(void *arg)
{
    SM_ARG *p = (SM_ARG *)arg;
    p->st.ns = s_init;
}

static inline void InitStateMachine(void *arg)
{
    ResetStateMachine(arg);
    EmyptData(arg);
}

#endif /* __FSM_H_ */
